from time import gmtime, strftime
import time
import timeit
import logging

from Strategy.config import CONFIG, STATIC

from MarketData.account import Account
from MarketData.const import CONST

from Strategy.account import Account_std, tieAccount_trade, tieAccount_withdraw, update_Account_fromOrder
from Strategy.model import evaluation, filter_Profit
from Strategy.quote import Quote_multithread, summarize_Quote, Quote_multithread_mid
from Strategy.order import create_newOrder, placeOrder_multithread
from Strategy.model_new import find_all_combination, find_best_pair, print_account_info, print_quote_result, \
    make_some_fake_account_balance, print_all_bids_asks, print_best_bid_ask, create_orders, print_new_orders, \
    print_order_return_info

from GUI.output import output_Array, output_MarketData, output_newOrder, output_Balance, PATH, output_Response


def trade_pairs(platform, currency):
    # 1. INPUT
    logging.info("#1. INPUT")
    # 1.1 parameter
    logging.info("#1.1 parameter")

    commodity_cur = currency[0]
    mid_cur = currency[1]
    base_cur = currency[2]

    # 每笔交易利润下限（单位是Base）
    ts_profit = CONFIG.TS_profit

    # 每笔交易利润下限（单位是Base）
    ts_profit_balance = CONFIG.TS_profit_balance

    # 滑单成本（单位是Base）
    perct_slippage = CONFIG.perct_slippage

    # 1.2.2 account balance
    logging.info("#1.2.2 account balance")

    time_now = timeit.default_timer()
    if time_now - STATIC.time_update > 300:  # hold for 5mins
        account = dict()
        account['trade'] = Account_std(STATIC.PlatformList_valid, 'trade')

        if account['trade']['bittrex'].balance['BTC'] == 0:
            return
        logging.info("Account balance updated with real platform.")
        print_account_info(account['trade'], True)
        output_Balance(CONST.CurrencyList, account, 'real')

        STATIC.account = account.copy()
        STATIC.time_update = time_now
    else:
        account = STATIC.account.copy()

    # 1.2.3 market quote
    # (price_bid, volume_bid, price_ask, volume_ask)
    logging.info("#1.2.3 market quote")

    start = timeit.default_timer()
    pairquote = Quote_multithread_mid(platform, commodity_cur, base_cur, mid_cur, 0)
    stop = timeit.default_timer()
    logging.info('%-10s%-10.2f' % ('Quote', stop - start))

    if stop - start > 2:
        logging.info('Too slow quote')
        return

    STATIC.price[commodity_cur, base_cur] = summarize_Quote(pairquote, commodity_cur, base_cur)
    STATIC.price[base_cur, commodity_cur] = 1.0 / STATIC.price[commodity_cur, base_cur]

    # make_some_fake_account_balance(account)
    print_account_info(account['trade'], False)
    output_Balance(CONST.CurrencyList, account, 'local')
    print_quote_result(pairquote)

    # 2. MODEL
    logging.info("#2. MODEL")

    asks, bids = find_all_combination(pairquote, commodity_cur, mid_cur, base_cur, account['trade'])
    print_all_bids_asks(asks, bids)

    best_ask, best_bid, profit = find_best_pair(asks, bids, ts_profit)
    if len(best_ask) == 0:
        pass
        return
    print_best_bid_ask(best_ask, best_bid, profit, ts_profit)

    # create order
    order_new = create_orders(commodity_cur, mid_cur, base_cur, best_ask, best_bid)
    print_new_orders(order_new)

    # return
    # 3. ORDER
    logging.info("#3. ORDER")
    start = timeit.default_timer()
    response = placeOrder_multithread(order_new)
    print_order_return_info(response)
    stop = timeit.default_timer()
    logging.info('%-10s%-10.2f' % ('Order', stop - start))

    # 4. Update Information
    logging.info("#4. UPDATE Local Account Balacne")
    # update local account balance
    update_Account_fromOrder(currency, perct_slippage, order_new, account['trade'])

    STATIC.account = account.copy()

    # return
    # 5. OUTPUT
    logging.info("#5. OUTPUT")

    # 5.1 market data
    output_MarketData(pairquote)

    # 5.2 new order, new balance
    if order_new:
        STATIC.time_update = timeit.default_timer()

        output_newOrder(order_new)
        output_Response(response)

    logging.info('')
